/*
 * compressedStream.h
 *
 *  Created on: May 25, 2012
 *      Author: Nico
 */


class OCompressedStream{
	protected:
		uInt blockSize;
		
		// Indica si ya se incluyo el blockSize
		bool blockSizeIncluded;
		
		OBitFileManager* bitManager;
		
		ofstream* output;
		
	public:
	
		// Si esta activado, incluye el blockSize al comienzo del 
		// archivo en codigo gamma
		bool includeBlockSize;
	
		OCompressedStream(const char* outputFilename,uInt blockSize);
		~OCompressedStream();
		
		// Escribe un entero en codigo gamma
		int writeIntAsGamma(uInt);
		
		// Escribe un numero en formato texto que ocupa 6 bytes
		int writeNumber(uInt number);
		
		// Escribe un texto normal en el archivo.
		int writeText(string* text);
		
		// Escribe el resultado de un RLE
		int writeRLEresult( string* L );
		
		// Escribe el resultado de un BlockSorting
		int writeBlockSortingResult( string* L , uInt I );
		
		// Escribe el resultado de un MTF
		int writeMTFResult (vector<uChar>* result);
		
		// Ecribe el resultado de comprimir un bloque de texto por Modelo Estructurado
		int writeModeloEstructuradoResult (const vector<string>* resultadosDeCadaNivel);
};

class ICompressedStream{
	
	protected:
		/* Atributos protegidos */
		const char* inputFilename;
		ifstream* input;
	
		uInt blockSize;
		
		// Indica si ya el blockSize que esta al comienzo
		// del archivo comprimido ya fue leido 
		bool blockSizeReaded;
		
		IBitFileManager* bitManager;
		
	private:
		/* Metodos privados */
		void init();
	
	public:
		ICompressedStream(const char* inputFilename);
		ICompressedStream(const char* inputFilename , uInt blockSize);
		~ICompressedStream();
		
		/* Atributos publicos */
		
		// Indica si el archivo comprimido comienza con un codigo
		// gamma del tamaño del bloque utilizado al comprimir
		bool startWithBlockSize;
		
		// Cantidad de chars leidos en la ultima lectura al archivo
		uInt lastReadAmount;
		
		// Si esta activado muestra debugs por pantalla
		bool debug;
		
		/* Metodos publicos */
		
		// Lee un codigo gamma.
		// En num deja el codigo gamma decodificado a entero.
		// En gamma deja el codigo gamma original.
		int readGamma(uInt* num , string* gamma );
		
		// Lee un codigo gamma sin devolver su representacion en bits
		int readGamma(uInt* num );
		
		// Lee un numero en una tira de 6 bytes
		int readNumber(uInt* num);
		
		// Lee un byte de texto
		int readByte(uChar* byte);

		// Lee un bloque entero (longitud en bytes)
		int readBlock(uInt blockSize,char** bytes);
		
		// Lee un bloque entero (longitud en bytes)
		int readBlock(uInt blockSize,string* bytes);
		
		// Utiliza this->blockSize como tamanio del bloque
		int readBlock(char** bytes);
				
		// Utiliza this->blockSize como tamanio del bloque
		int readBlock(string* bytes);
		
		// Lee el resultado de un BlockSorting
		int readBlockSortingResult( string* L , uInt* I );
		
		// Lee el resultado de un MTF
		int readMTFresult(char**);
};
